﻿Imports System.Collections.ObjectModel
Imports PTIC_Util
Imports System.Data.OleDb
Imports System.Collections.Specialized

<Serializable()> Public Class ParametreSelectionMedicale_Etat
    Private _parametre As ParametreSelectionMedicale
    Public Sub New(ByVal parametre As ParametreSelectionMedicale)
        _parametre = parametre
    End Sub
    Protected ReadOnly Property Parametre As ParametreSelectionMedicale
        Get
            Return _parametre
        End Get
    End Property

    Public Sub MAJValeurs()

        'Récupération des noms de colonnes à affecter à la table des valeurs
        Dim nomNbAnneesDeroulement As String = ParametreSelectionMedicale.nomNbAnneesDeroulement
        Dim nomAbattementSelMedi As String = ParametreSelectionMedicale.nomAbattementSelMedi

        If Parametre.ListeSegments.Count = 0 Then
            'La nouvelle valeur du paramètre n'est pas segmentée

            'Création de la nouvelle table des valeurs
            Dim TValeur As New DataTable
            TValeur.Columns.Add(nomNbAnneesDeroulement, GetType(Integer))
            TValeur.Columns.Add(nomAbattementSelMedi, GetType(Double))

            'Création d'une table intermédiaire contenant les valeurs des taux d'abattement à agréger
            Dim valIntermediaires(Parametre.maxDeroulement - 1, 1) As Double
            For Each row As DataRow In Parametre.Valeurs.Rows
                valIntermediaires(row(nomNbAnneesDeroulement) - 1, 0) _
                    = valIntermediaires(row(nomNbAnneesDeroulement) - 1, 0) + _
                    row(nomAbattementSelMedi)
                valIntermediaires(row(nomNbAnneesDeroulement) - 1, 1) _
                    = valIntermediaires(row(nomNbAnneesDeroulement) - 1, 1) + 1
            Next

            'Alimentation de la nouvelle table des valeurs
            For i As Integer = 1 To Parametre.maxDeroulement
                Dim r As DataRow = TValeur.NewRow
                r(nomNbAnneesDeroulement) = i
                r(nomAbattementSelMedi) = valIntermediaires(i - 1, 0) / valIntermediaires(i - 1, 1)
                TValeur.Rows.Add(r)
            Next

            Parametre.Valeurs = TValeur

        ElseIf _parametre.Nature = ParamNature.Declinee Then
            'La nouvelle valeur du paramètre est déclinée
            Parametre.Requete.Calculer_DataTable()
            Dim ValExt As DataTable = Parametre.Requete.DataTableResultat

            'L'ancienne valeur n'est pas déclinée
            If Parametre.Valeurs.Columns.Count = 2 Then
                Dim Tvaleur As New DataTable
                For Each col As DataColumn In ValExt.Columns
                    Tvaleur.Columns.Add(col.ColumnName, col.DataType)
                    Tvaleur.Columns(col.ColumnName).Caption = col.Caption
                Next
                Tvaleur.Columns.Add(nomNbAnneesDeroulement, GetType(Integer))
                Tvaleur.Columns.Add(nomAbattementSelMedi, GetType(Double))

                For Each r As DataRow In ValExt.Rows
                    For Each rowValEnCours As DataRow In Parametre.Valeurs.Rows
                        Dim newRow As DataRow = Tvaleur.NewRow
                        For Each col As DataColumn In ValExt.Columns
                            newRow(col.ColumnName) = r(col.ColumnName)
                        Next
                        newRow(nomNbAnneesDeroulement) = rowValEnCours(nomNbAnneesDeroulement)
                        newRow(nomAbattementSelMedi) = rowValEnCours(nomAbattementSelMedi)
                        Tvaleur.Rows.Add(newRow)
                    Next
                Next
                Parametre.Valeurs = Tvaleur

            ElseIf Parametre.Valeurs.Columns.Count > 2 Then
                'L'ancienne valeur du paramètre est déclinée
                Dim copyValeurs As DataTable = Parametre.Valeurs.Copy
                Dim copyValExt As DataTable = ValExt.Copy

                'Défintion des pramètres
                Dim coll_segmentRelation As New List(Of String)
                Dim tabCol_Extraction() As DataColumn
                Dim tabCol_anciennesValeurs() As DataColumn

                'Liste des segment intervenant dans la jointure (communs aux deux tables)
                For Each nomCol As String In Parametre.ListeSegments
                    For Each colVal As DataColumn In copyValeurs.Columns
                        If colVal.Caption = nomCol Then
                            coll_segmentRelation.Add(colVal.ColumnName)
                        End If
                    Next
                Next

                'Création des tableaux contenant les champs de l'extraction et de la valeur courante à inclure dans la jointure
                ReDim tabCol_Extraction(coll_segmentRelation.Count - 1)
                ReDim tabCol_anciennesValeurs(coll_segmentRelation.Count - 1)
                Dim i As Integer = 0
                For Each s As String In coll_segmentRelation
                    Dim nomSegment As String = s
                    tabCol_Extraction(i) = copyValExt.Columns(s)
                    tabCol_anciennesValeurs(i) = copyValeurs.Columns(s)
                    i = i + 1
                Next

                'Création de la nouvelle table contenant le résultat de la jointure
                Dim ds As DataSet
                ds = New DataSet
                ds.Tables.Add(copyValeurs)
                ds.Tables.Add(copyValExt)
                ds.Relations.Add("relSelMedic", tabCol_Extraction, tabCol_anciennesValeurs, False)
                'Faire une copie de la table car elle appartient déjà à un dataSet.

                'Création d'une table contenant les nouvelles valeurs + Ajout de toutes les colonnes à cette table
                Dim nouvellesValeurs As New DataTable
                For Each col As DataColumn In copyValExt.Columns
                    nouvellesValeurs.Columns.Add(col.ColumnName, col.DataType)
                Next
                nouvellesValeurs.Columns.Add(nomNbAnneesDeroulement, GetType(Integer))
                nouvellesValeurs.Columns.Add(nomAbattementSelMedi, GetType(Double))


                For Each rowExt As DataRow In copyValExt.Rows

                    'Un segment a été retiré
                    If rowExt.GetChildRows("relSelMedic").Count > 1 Then
                        Dim rowEnfants(Parametre.maxDeroulement - 1) As DataRow
                        For k As Integer = 0 To Parametre.maxDeroulement - 1
                            rowEnfants(k) = nouvellesValeurs.NewRow
                            For Each col As DataColumn In copyValExt.Columns
                                rowEnfants(k)(col.ColumnName) = rowExt(col.ColumnName)
                            Next
                            rowEnfants(k)(nomAbattementSelMedi) = 0
                            rowEnfants(k)(nomNbAnneesDeroulement) = k + 1
                        Next
                        Dim poidsValeurs(Parametre.maxDeroulement - 1) As Double
                        For Each childRow As DataRow In rowExt.GetChildRows("relSelMedic")
                            Dim numDeroulement As Integer = childRow(nomNbAnneesDeroulement)
                            rowEnfants(numDeroulement - 1)(nomAbattementSelMedi) = rowEnfants(numDeroulement - 1)(nomAbattementSelMedi) + childRow(nomAbattementSelMedi)
                            poidsValeurs(numDeroulement - 1) = poidsValeurs(numDeroulement - 1) + 1
                        Next
                        For k As Integer = 0 To Parametre.maxDeroulement - 1
                            rowEnfants(k)(nomAbattementSelMedi) = rowEnfants(k)(nomAbattementSelMedi) / poidsValeurs(k)
                            nouvellesValeurs.Rows.Add(rowEnfants(k))
                        Next


                    Else
                        'Un segment a été ajouté
                        For Each childRow As DataRow In rowExt.GetChildRows("relSelMedic")
                            Dim newRow As DataRow = nouvellesValeurs.NewRow
                            For Each col As DataColumn In nouvellesValeurs.Columns
                                If copyValExt.Columns.Contains(col.ColumnName) Then
                                    newRow(col.ColumnName) = rowExt(col.ColumnName)
                                Else
                                    newRow(col.ColumnName) = childRow(col.ColumnName)
                                End If
                            Next
                            nouvellesValeurs.Rows.Add(newRow)
                        Next

                    End If

                Next

                Parametre.Valeurs = nouvellesValeurs
                For Each col As DataColumn In ValExt.Columns
                    If Parametre.Valeurs.Columns.Contains(col.ColumnName) Then
                        Parametre.Valeurs.Columns(col.ColumnName).Caption = col.Caption
                    End If
                Next
                'ds.Relations.Clear()
                'ds.Tables.Clear()
                ds = Nothing
                'NotifieChangement(Me, Nothing)
            End If

            'Il faut :
            '   - exécuter la requête
            '   - récupérer le résultat dans une table
            '   - ajouter les déroulement dans la table des résultats
            '   - Faire la liste de tous les champs communs à l'ancienne table des valeurs
            '     et la nouvelle table des valeurs
            '   - Parcourir tous les champs de la nouvelle table et faire 2 cas selon le
            '     nombre d'enfants :
            '       - Cas N°1 : un seul enfant : on recopie le résultat
            '       - Cas N°2 : plusieurs enfants : on fait la moyenne

            'Détermination de la nature du changement de segmentation (ajout ou retrait de segment)
            'Dim segmentsRetires As Boolean = False
            'Dim coll_segmentsActuel As ObservableCollection(Of String) = Me.ListeSegments
            'For Each segment As String In coll_segmentsActuel
            '    If Not valeursExtraction.Columns.Contains(segment) Then
            '        segmentsRetires = True
            '    End If
            'Next
            'setValeursFromExt_ValDecl(valeursExtraction, segmentsRetires)
        End If

    End Sub
    Public Sub Deserialize(ByVal param As ParametreSelectionMedicale)

        'Sauvegarde des caractéristiques actuelles du paramètre
        Dim AnciennesValeurs As DataTable = Me.Parametre.Valeurs.Copy
        Dim AnciensSegments As New Collection(Of String)
        For Each seg As String In Me.Parametre.ListeSegments
            AnciensSegments.Add(seg)
        Next
        Dim AncienNbDeroulement As Integer = param.maxDeroulement

        'Remise à 0 du déroulement maximum
        Me.Parametre.maxDeroulement = 1

        'Alimentation des nouveaux segments du paramètre en fonction des valeurs sauvegardées
        Dim lSegments As ObservableCollection(Of String) = param.ListeSegments
        Me.Parametre.ListeSegments.Clear()
        For Each seg As String In lSegments
            Me.Parametre.ListeSegments.Add(seg)
        Next
        Me.Parametre.maxDeroulement = param.maxDeroulement
        MAJValeurs()

        'Ici, les segments serializés sont renseignés dans le paramètre
        'Les valeurs sont alimentées à partir des anciennes valeurs
        'Maintenant, on va cherche à alimenter les valeurs sérializées dans le paramètre
        Dim valeurs_copy As DataTable = Me.Parametre.Valeurs.Copy
        Dim valeurs_Serializees_copy As DataTable = param.Valeurs.Copy

        Dim colValeurs(lSegments.Count) As DataColumn
        Dim colValeursSerializees(lSegments.Count) As DataColumn
        Dim i As Integer = 0
        For Each col As DataColumn In valeurs_Serializees_copy.Columns
            If valeurs_copy.Columns.Contains(col.ColumnName) _
                And col.ColumnName <> Me.Parametre.Nom _
                And col.ColumnName <> ParametreSelectionMedicale.nomAbattementSelMedi Then
                colValeurs(i) = valeurs_copy.Columns(col.ColumnName)
                colValeursSerializees(i) = col
                i = i + 1
            End If
        Next

        'Création de la nouvelle table contenant le résultat de la jointure
        Dim ds As DataSet
        valeurs_Serializees_copy.TableName = "ValeursSerializees"
        ds = New DataSet
        ds.Tables.Add(valeurs_copy)
        ds.Tables.Add(valeurs_Serializees_copy)
        ds.Relations.Add("relParametre", colValeurs, colValeursSerializees, False)

        'Parcours de la relation ligne à ligne
        Dim isOk As Boolean = True
        For Each newTableRow As DataRow In valeurs_copy.Rows
            'Récupérer les enfants de la ligne
            Dim ChildRows() As DataRow = newTableRow.GetChildRows("relParametre")

            If ChildRows.Count = 0 Then
                'La ligne contient plusieurs enfants
                'Pas de correspondance pour la ligne en cours
                isOk = False

            Else
                'La ligne ne contient qu'un seul enfant
                newTableRow(ParametreSelectionMedicale.nomAbattementSelMedi) = _
                    ChildRows(0)(ParametreSelectionMedicale.nomAbattementSelMedi)

            End If
        Next
        If Not isOk Then
            MsgBox("Le chargement du paramètre " & Me.Parametre.Nom & " n'a pas pu être effectuée entièrement car certaines valeurs du paramètre n'avaient pas de correspondance dans la sauvegarde.")
        End If
        ds.Relations.Clear()
        ds.Tables.Remove(valeurs_copy)
        ds.Tables.Remove(valeurs_Serializees_copy)
        Me.Parametre.Valeurs = valeurs_copy
    End Sub
    Public Sub onListeSegmentsChanged(ByVal sender As Object, ByVal e As System.Collections.Specialized.NotifyCollectionChangedEventArgs)
    End Sub

End Class
